
import dayjs, { ManipulateType } from 'dayjs';
import { timeRegex } from './verification'

/**
 * 找出字符串中所有的类似日期的字符串
 * @param  str 含有日期的字符串
 * @param  separator 时间间隔
 * @returns 
 */
export function matchAllTime(str: string, separator = '-'): string[] {
  const result = []
  let match;
  while (match = timeRegex.exec(str)) {
    const list = Array.from(match)
    list.shift()
    result.push(list.join(separator))
  }
  return result
}

/**
 *
 * 开始时间
 * @param {Date|string} dateObj 时间对象
 * @returns {String} 时间字符串: yyyy-MM-dd 00:00:00
 */
export function dateStartFormat(dateObj: string | Date = new Date()): string {
  if (typeof dateObj === 'string') {
    const [first] = matchAllTime(dateObj)
    return first ? first + ' 00:00:00' : ''
  }
  const year = dateObj.getFullYear()
  const month = numberToPad((dateObj.getMonth() + 1), 2)
  const day = numberToPad(dateObj.getDate(), 2)
  return `${year}-${month}-${day} 00:00:00`
}
/**
 *
 * 结束时间
 * @param {Date|string} dateObj 时间对象
 * @returns {String} 时间字符串: yyyy-MM-dd 23:59:59
 */
export function dateEndFormat(dateObj: Date | string = new Date()): string {
  if (typeof dateObj === 'string') {
    const [first] = matchAllTime(dateObj)
    return first ? first + ' 23:59:59' : ''
  }
  const year = dateObj.getFullYear()
  const month = numberToPad((dateObj.getMonth() + 1), 2)
  const day = numberToPad(dateObj.getDate(), 2)
  return `${year}-${month}-${day} 23:59:59`
}

/**
 * 格式化时间数组,将数组内的时间对象第一个格式化时间是00:00:00,第二个时间对象时间格式化为23:59:59
 * 传入第二个参数可以国际化参数,即有可能用户自定义查询时区
 * @param {Array<string|Date>} arr 
 * @returns  格式化好以后的时间区间字符串
 * @example 
 * getDateArrayToStrRange([new Date(),new Date()]) //return {start:'xxxx-xx-xx 00:00:00' ,end :'xxxx-xx-xx 23:59:59'}
 * getDateArrayToStrRange() //return {start:'' ,end :''}
 */
export function getDateArrayToStrRange(arr?: (Date | string)[], options?: { timeOffset?: string | number, start: string, end: string }) {
  const base: { start?: string, end?: string, timeDifference?: string } = {}
  let start: string = 'start', end: string = 'end', timeOffset: string | number | undefined
  if (options) {
    ({ start = 'start', end = 'end', timeOffset } = options)
  }
  if (Array.isArray(arr) && arr.length >= 2) {
    const [f, s] = arr
    Object.assign(base, { [start]: dateStartFormat(f), [end]: dateEndFormat(s) })
  }
  if (timeOffset) {
    Object.assign(base, { timeDifference: timeOffset })
  }
  return base
}

/**
 * 给出某年,月,日,减去指定数字后的时间
 * @param {Number} number 
 * @param {Date} date 
 * @param {String} flag 
 * @returns 
 */
export function getMonthByLastTime(number = 2, date = new Date(), flag: ManipulateType = "month") {
  const time = dayjs(date).subtract(number, flag)
  return new Date(time.year(), time.month(), time.date(), time.hour(), time.minute(), time.second())
}
/**
 *
 * @param {String} dateStr  时间字符串
 * @returns 提取其中的 yyy-MM-dd HH:mm:ss
 */
export function dateStringFormat(dateStr: string) {
  const reg = /(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/i
  let [, date] = Array.from(reg.exec(dateStr) || '')
  return date
}
/**
 *
 * @param {Number} num 修改数字长度,并转化为字符串
 * @param {Number} length 修改数字长度,并转化为字符串
 *
 */
export function numberToPad(num: number, length: number) {
  if (typeof num !== 'number' || typeof length !== 'number') throw new TypeError('请传入数字')
  return num.toString().padStart(length, '0')
}
/**
 *
 * @param {Date} dateObj 时间对象
 * @returns {String} 时间字符串: yyyy-MM-dd HH:mm:ss
 */
export function dateObjToStringYMDHS(dateObj = new Date()) {
  const year = dateObj.getFullYear()
  const month = numberToPad((dateObj.getMonth() + 1), 2)
  const day = numberToPad(dateObj.getDate(), 2)
  const hour = numberToPad(dateObj.getHours(), 2)
  const minutes = numberToPad(dateObj.getMinutes(), 2)
  const secorde = numberToPad(dateObj.getSeconds(), 2)
  return `${year}-${month}-${day} ${hour}:${minutes}:${secorde}`
}

/**
 *
 * @param {Date} tempDateObj  给出指定时间所在的周的时间区间
 * @returns {Array} 时间数组,长度为2,索引为0的时间更小
 */
export function getDateRangeByWeek(tempDateObj = new Date()) {
  tempDateObj.setDate(tempDateObj.getDate() - (tempDateObj.getDay() - 1))
  const dateStart = new Date(tempDateObj.getFullYear(), tempDateObj.getMonth(), tempDateObj.getDate(), 0, 0, 0)
  tempDateObj.setDate(tempDateObj.getDate() + 7)
  const dateEnd = new Date(tempDateObj.getFullYear(), tempDateObj.getMonth(), tempDateObj.getDate(), 23, 59, 59)
  return [dateStart, dateEnd]
}
/**
 *
 * @param {Date} tempDateObj 给出指定日期的当月时间区间
 * @returns {Array} 时间数组,长度为2,索引为0的时间更小
 */
export function getDateRangeByMonth(tempDateObj = new Date()) {
  const startDate = new Date(tempDateObj.getFullYear(), tempDateObj.getMonth(), 1, 0, 0, 0)
  const month = tempDateObj.getMonth() + 1
  const fullYear = tempDateObj.getFullYear()
  if ([1, 3, 5, 7, 8, 10, 12].includes(month)) {
    return [startDate, new Date(fullYear, tempDateObj.getMonth(), 31, 23, 59, 59)]
  } else if ([4, 6, 9, 11].includes(month)) {
    return [startDate, new Date(fullYear, tempDateObj.getMonth(), 30, 23, 59, 59)]
  }
  const isLeapYear = (fullYear % 4 === 0 && (fullYear % 100 !== 0 || fullYear % 400 == 0))
  return [startDate, new Date(fullYear, tempDateObj.getMonth(), isLeapYear ? 29 : 28, 23, 59, 59)]
}
/**
 *
 * @param {Date} tempDateObj 给出指定日期年份的时间区间
 * @returns {Array} 时间数组,长度为2,索引为0的时间更小
 */
export function getCurrentYearRange(tempDateObj = new Date()) {
  const startDate = new Date(tempDateObj.getFullYear(), 0, 1)
  const endDate = new Date(tempDateObj.getFullYear(), 11, 31)
  return [startDate, endDate]

}

/**
 *
 *当前时间往前推30天
 * @returns {Array} 时间数组,长度为2
 */
export function getMonthAll() {
  let currentDate = new Date();
  //获取三十天前日期
  return [getMonthByLastTime(30, new Date(), 'D'), currentDate];
}

/**
 *
 * 单个日期1
 * @param {Date|string} dateObj 时间对象
 * @returns {String} 时间字符串: yyyy-MM-dd
 */
export function dateFormat(dateObj = new Date()) {
  const year = dateObj.getFullYear()
  const month = numberToPad((dateObj.getMonth() + 1), 2)
  const day = numberToPad(dateObj.getDate(), 2)
  return `${year}-${month}-${day}`
}

/**
 *
 * 当前年的时间区间
 * @param {Date|string} dateObj 时间对象
 * @returns {String} 时间字符串: yyyy-MM-dd 00:00:00
 */
export function dateYearFormat(dateObj = new Date()) {
  const year = dateObj.getFullYear()
  const startDate = `${year}-01-01 00:00:00`
  const endDate = `${year}-12-31 23:59:59`
  return [startDate, endDate]
}
